home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-05
/
lanutsrc.zip
/
CONFIG.C
< prev
next >
Wrap
Text File
|
1991-03-13
|
16KB
|
746 lines
#pragma inline
/*********************************/
/* */
/* CONFIG.C - by Mike Klein */
/* */
/* ver 2.0 */
/* */
/*-------------------------------*/
/* */
/* A routine to show computer's */
/* configuration and optionally */
/* alter the parent environment */
/* SETting variables based upon */
/* the status of/equipment found */
/* in the computer being used. */
/* */
/*-------------------------------*/
/* */
/* FINISHED: 07/13/89 */
/* */
/*********************************/
/**************************************************/
/* */
/* NOTE: Users experiencing difficulty compiling */
/* will probably want to remove the references to */
/* in-line assembly code. This is used only in */
/* the CPU determining function. Also remove the */
/* #pragma inline statement at the top of the */
/* listing. Remember to compile with byte */
/* alignment. The following are some function */
/* definitions that your compiler may not support */
/* directly. Use these defines to include them */
/* if that is the case. */
/* */
/**************************************************/
/*
#define MK_FP(seg,ofs) ((void far *) \
(((unsigned long)(seg) << 16) | (unsigned)(ofs)))
#define poke(a, b, c) (*((int far *) MK_FP((a), (b))) = (int) (c))
#define pokeb(a, b, c) (*((char far *) MK_FP((a), (b))) = (char) (c))
#define peek(a, b) (*((int far *) MK_FP((a), (b))))
#define peekb(a, b) (*((char far *) MK_FP((a), (b))))
*/
/*****************/
/* */
/* INCLUDE FILES */
/* */
/*****************/
#include <string.h>
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
/***********/
/* */
/* DEFINES */
/* */
/***********/
#define VERSION 2.0
#define TRUE 1
#define FALSE 0
#define VOID void
#define intvideo(regs) int86(0x10, regs, regs)
#define intmouse(regs) int86(0x33, regs, regs)
/*************/
/* */
/* TYPEDEF'S */
/* */
/*************/
typedef signed char BOOLEAN;
typedef unsigned char BYTE;
typedef signed char CHAR;
typedef signed int INT;
typedef unsigned int COUNTER;
typedef unsigned int SEGMENT;
typedef unsigned int LENGTH;
CHAR far *par_env; /* Pointer to parent environment */
LENGTH par_env_len; /* Length of parent environment */
/****************/
/* */
/* DECLARATIONS */
/* */
/****************/
VOID put_par_env(CHAR *env_var, CHAR *env_text);
VOID del_par_env(CHAR *env_var);
/********/
/* */
/* MAIN */
/* */
/********/
VOID main(COUNTER argc, CHAR *argv[])
{
CHAR *class; /* Like model, but only (PC/AT) */
CHAR conv[4]; /* Conventional memory size */
CHAR *cpu; /* CPU type (808x, 80286, 80386) */
CHAR date[9]; /* System date */
CHAR *exp; /* Expanded memory? (YES/NO) */
CHAR *ext; /* Extended memory? (YES/NO) */
CHAR *fpu; /* FPU present? (YES/NO) */
CHAR *mca; /* Micro Channel? (YES/NO) */
CHAR *mode; /* Video mode (COLOR/MONOCHROME) */
CHAR *model; /* Model (PC/XT/XT-286/AT/25/30/50 */
/* 60/70/80) */
CHAR *mouse; /* Mouse present? (YES/NO) */
CHAR rom_date[9]; /* Computer's rom date */
CHAR *ps2; /* PS/2 system? (YES/NO) */
CHAR version[5]; /* DOS version (2.0, 3.3, etc.) */
CHAR *video; /* Video adapter (MDA, HERC, CGA, */
/* EGA, PGA, VGA, */
/* MCGA) */
BYTE byte;
BYTE main;
BYTE sub;
BYTE features;
CHAR far *far_ptr;
SEGMENT far *seg_ptr;
CHAR *emm_id;
int env_set = FALSE;
COUNTER i;
union REGS regs;
struct SREGS sregs;
struct date system_date;
/* Structs for PSP and DOS Memory Control Block (MCB) */
typedef struct
{
CHAR misc1[22];
SEGMENT par_seg;
CHAR misc2[20];
SEGMENT env_seg;
} PSP;
/* Compile with byte alignment */
typedef struct
{
CHAR status; /* Block is in chain or not */
SEGMENT owner_psp; /* PSP segment of block's owner */
LENGTH size; /* Size (in paragraphs) of block */
} MCB;
MCB far *config_mcb; /* config.sys MCB */
MCB far *command_mcb; /* command.com MCB */
MCB far *env_mcb; /* environments MCB */
PSP far *command_psp; /* command.com PSP */
/***************************/
/* */
/* COMMAND LINE PARAMETERS */
/* */
/***************************/
if(argc > 1)
if(!strcmp(argv[1], "/e") || !strcmp(argv[1], "/E"))
env_set = TRUE;
else
{
puts("\nERROR: Bad parameter...");
exit(-1);
}
else
env_set = FALSE;
/***************************/
/* */
/* FIND PARENT ENVIRONMENT */
/* */
/***************************/
regs.x.ax = 0x5200;
intdosx(®s, ®s, &sregs);
seg_ptr = MK_FP(sregs.es, regs.x.bx - 2);
config_mcb = MK_FP(*seg_ptr, 0);
command_psp = MK_FP(FP_SEG(config_mcb) + config_mcb->size + 2, 0);
if(command_psp->env_seg == 0)
{
/* Environment is in block after parent program */
command_mcb = MK_FP(FP_SEG(config_mcb) + config_mcb->size + 1, 0);
par_env = MK_FP(FP_SEG(command_mcb) + command_mcb->size + 2, 0);
}
else /* We have pointer to environment */
par_env = MK_FP(command_psp->env_seg, 0);
/* MCB of environment is 1 segment lower */
env_mcb = MK_FP(FP_SEG(par_env) - 1, 0);
par_env_len = env_mcb->size * 16; /* Save len of environment */
printf("\n\nSYSTEM CONFIGURATION v%1.1f\n", VERSION);
puts("=========================");
/*************/
/* */
/* MODEL/MCA */
/* */
/*************/
byte = peekb(0xf000, 0xfffe); /* Get model byte */
mca = "NO";
ps2 = "NO";
switch(byte)
{
case 0xff :
model = "PC";
break;
case 0xfe :
case 0xfb :
model = "XT";
break;
case 0xfc :
case 0xfa :
case 0xf8 :
regs.x.ax = 0xc000; /* Get the system environment info */
int86x(0x15, ®s, ®s, &sregs);
main = peekb(sregs.es, regs.x.bx + 2);
if(byte != main) /* Some AT's don't support this */
{ /* function so let's abort */
model = "AT";
break;
}
sub = peekb(sregs.es, regs.x.bx + 3);
features = peekb(sregs.es, regs.x.bx + 5);
if(features & 0x02)
mca = "YES";
switch(main)
{
case 0xfc :
switch(sub)
{
case 0x02 :
model = "XT286";
break;
case 0x04 :
model = "50";
ps2 = "YES";
break;
case 0x05 :
model = "60";
ps2 = "YES";
break;
case 0x00 :
case 0x01 :
default :
model = "AT";
break;
}
break;
case 0xf8 :
ps2 = "YES";
switch(sub)
{
case 0x00 :
case 0x01 :
model = "80";
break;
case 0x04 :
case 0x09 :
default :
model = "70";
break;
}
break;
case 0xfa :
ps2 = "YES";
switch(sub)
{
case 0x01 :
model = "25";
break;
case 0x00 :
default :
model = "30";
break;
}
break;
default :
model = "N/A";
break;
}
break;
default :
model = "N/A";
break;
}
printf("MODEL.....%s\n", model);
printf("PS/2......%s\n", ps2);
printf("MCA.......%s\n", mca);
if(env_set)
{
put_par_env("MODEL", model);
put_par_env("PS/2", ps2);
put_par_env("MCA", mca);
}
/************/
/* */
/* CPU TYPE */
/* */
/************/
asm pushf
asm xor ax,ax
asm push ax
asm popf
asm pushf
asm pop ax
asm and ax,0f000h
asm cmp ax,0f000h
asm jz is_808x
asm mov ax,07000h /* If we can't set bits 12-14 then */
asm push ax /* CPU is 80286 */
asm popf
asm pushf
asm pop ax
asm and ax,07000h
asm jz is_80286
is_80386 :
asm mov ax,386h
asm jmp done
is_80286 :
asm mov ax,286h
asm jmp done
is_808x :
asm mov ax,86h
done:
asm popf
switch(_AX)
{
case 0x386 :
cpu = "80386";
class = "AT";
break;
case 0x286 :
cpu = "80286";
class = "AT";
break;
case 0x86 :
cpu = "808x";
class = "PC";
break;
default :
cpu = "N/A";
break;
}
printf("CPU.......%s\n", cpu);
printf("CLASS.....%s\n", class);
if(env_set)
{
put_par_env("CPU", cpu);
put_par_env("CLASS", class);
}
/**************/
/* */
/* MATH CHIP? */
/* */
/**************/
int86(0x11, ®s, ®s); /* Get BIOS equip word for FPU */
fpu = (regs.x.ax & 0x02) ? "YES" : "NO";
printf("FPU.......%s\n", fpu);
if(env_set)
put_par_env("FPU", fpu);
/************/
/* */
/* GET DATE */
/* */
/************/
regs.x.ax = 0x0400;
int86(0x1a, ®s, ®s);
sprintf(date, "%02x/%02x/%02x", regs.h.dh, regs.h.dl, regs.h.cl);
printf("DATE......%s\n", date);
if(env_set)
put_par_env("DATE", date);
/***********************/
/* */
/* CONVENTIONAL MEMORY */
/* */
/***********************/
int86(0x12, ®s, ®s); /* INT 0x12 returns conv memory */
if((regs.x.ax % 2) != 0) /* Some systems report 1K less */
++regs.x.ax; /* than actual, so we compensate */
sprintf(conv, "%u", regs.x.ax);
printf("CONV......%s\n", conv);
if(env_set)
put_par_env("CONV", conv);
/*******************/
/* */
/* EXPANDED MEMORY */
/* */
/*******************/
emm_id = "EMMXXXX0";
regs.x.ax = 0x3567;
intdosx(®s, ®s, &sregs);
far_ptr = MK_FP(sregs.es, 10);
for(i=0; i < 8; i++)
{
if(far_ptr[i] != emm_id[i])
{
exp = "NO";
break;
}
}
if(i == 8)
{
exp = "YES";
regs.h.ah = 0x42;
int86(0x67, ®s, ®s);
}
printf("EXP.......%s", exp);
if(i == 8)
printf(" (%dK)\n", regs.x.bx * 16);
else
printf("\n");
if(env_set)
put_par_env("EXP", exp);
/*******************/
/* */
/* EXTENDED MEMORY */
/* */
/*******************/
/* This code must follow the CPU code */
if(! strcmp(class, "AT"))
{
regs.x.ax = 0x8800;
int86(0x15, ®s, ®s);
i = regs.x.ax;
if((i != 0x8800) && (i != 0x0000))
ext = "YES";
else
ext = "NO";
}
else
ext = "NO";
printf("EXT.......%s", ext);
if(!strcmp(ext, "YES"))
printf(" (%dK)\n", i);
else
printf("\n");
if(env_set)
put_par_env("EXT", ext);
/**********/
/* */
/* MOUSE? */
/* */
/**********/
regs.x.ax = 0x00; /* Mouse Func 0 - initialize */
intmouse(®s);
if(regs.x.ax)
mouse = "YES";
else
mouse = "NO";
printf("MOUSE.....%s\n", mouse);
if(env_set)
put_par_env("MOUSE", mouse);
/************/
/* */
/* ROM DATE */
/* */
/************/
far_ptr = MK_FP(0xf000, 0xfff5); /* Make pointer to address */
/* of computer's rom date */
if(far_ptr[2] == far_ptr[5])
{
for(i=0; i<8; ++i)
rom_date[i] = far_ptr[i]; /* Make string from far_ptr */
rom_date[i] = '\0';
}
else
strcpy(rom_date, "N/A");
printf("ROM DATE..%s\n", rom_date);
if(env_set)
put_par_env("ROM_DATE", rom_date);
/**************/
/* */
/* VIDEO MODE */
/* */
/**************/
regs.x.ax = 0x0f00;
intvideo(®s);
switch(regs.h.al)
{
case 0x00 :
case 0x02 :
case 0x07 :
mode = "MONOCHROME";
break;
default :
mode = "COLOR";
break;
}
printf("MODE......%s\n", mode);
if(env_set)
put_par_env("MODE", mode);
/*****************/
/* */
/* VIDEO ADAPTER */
/* */
/*****************/
regs.x.ax = 0x1a00; /* If function supported (_AL=0x1A) */
intvideo(®s);
if(regs.h.al == 0x1a)
{
switch(regs.h.bl)
{
case 0x01 :
video = "MDA";
break;
case 0x02 :
video = "CGA";
break;
case 0x04 :
case 0x05 :
video = "EGA";
break;
case 0x06 :
video = "PGA";
break;
case 0x07 :
case 0x08 :
video = "VGA";
break;
case 0x0a :
case 0x0b :
case 0x0c :
video = "MCGA";
break;
default :
video = "VGA";
break;
}
}
else
{
regs.h.ah = 0x12; /* Get config info for EGA/VGA */
regs.h.bl = 0x10;
intvideo(®s);
if(regs.h.bl != 0x10)
video = "EGA"; /* BL changed? Then EGA */
else
{
regs.h.ah = 0x0f; /* See if color or mono */
intvideo(®s);
if(regs.h.al == 7)
{ /* Read CRT status port, mask bit 7 */
byte = inport(0x3ba) & 0x80;
for(i = 0; i < 32767; i++) /* Will bit 7 change? */
if(byte != inport(0x3ba) & 0x80)
break; /* If bit 7 didn't change, then MDA */
video = (i != 32767) ? "HERC" : "MDA";
}
else
video = "CGA";
}
}
printf("VIDEO.....%s\n", video);
if(env_set)
put_par_env("VIDEO", video);
/***************/
/* */
/* DOS VERSION */
/* */
/***************/
regs.h.ah = 0x30; /* INT 0x21 FUNC 0x30 to get DOS */
intdos(®s, ®s); /* version number */
sprintf(version, "%u.%u", (unsigned) regs.h.al, (unsigned) regs.h.ah);
printf("VERSION...%s\n", version);
if(env_set)
put_par_env("VERSION", version);
puts("=========================\n");
}
/***************/
/* */
/* PUT_PAR_ENV */
/* */
/***************/
VOID put_par_env(CHAR *env_var, CHAR *env_text)
{
CHAR far *far0;
LENGTH len;
CHAR env_str[256];
CHAR *str;
strcpy(env_str, env_var); /* Create environment string */
strcat(env_str, "=");
strcat(env_str, env_text);
strupr(env_str);
del_par_env(env_var); /* Delete variable of same name */
/* Find end of environment by looking for 2 NULLS */
for(far0 = par_env, len = 0; !(!*far0 && !*(far0+1)); ++far0, ++len)
;
len = par_env_len - (len + 2); /* Get free space in environment */
if(len < strlen(env_str) + 1)
{ /* If out of room, return error */
puts("\nERROR: Out of environment space...\n");
exit(-1);
}
str = env_str;
for(++far0; *str; *far0++ = *str++) /* Copy str to end of par env */
;
*far0 = 0; /* End env with 2 nulls */
++far0;
*far0 = 0;
}
/***************/
/* */
/* DEL_PAR_ENV */
/* */
/***************/
VOID del_par_env(CHAR *env_var)
{
CHAR far *far1; /* Beginning of next variable */
CHAR far *far2; /* Beginning of the variable */
CHAR *str; /* env_var ptr used in search */
int found = FALSE; /* End of search flag */
far1 = par_env;
while(*far1 && !found)
{ /* Find start of variable to delete */
str = env_var;
far2 = far1;
for(;(*far1 == *str) && (*far1 != '=') && *far1 && *str; ++far1, ++str)
;
if((!*str) && (*far1 == '='))
found = TRUE; /* We found it! */
for(; *far1; ++far1)
;
++far1;
}
if(!*far1 && !found) /* Find env_var? */
return; /* No, we didn't */
/* Shift environment down, to cover env_var */
for(; !(!*far1 && !*(far1+1)); *far2++ = *far1++)
;
*far2 = 0; /* End env with 2 nulls */
++far2;
*far2 = 0;
}